package com.shenyaocn.android.dualcamera;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.YuvImage;
import android.hardware.usb.UsbDevice;
import android.media.AudioRecord;
import android.os.Bundle;
import android.os.Handler;
import android.os.Environment;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.DeviceFilter;
import com.serenegiant.usb.IFrameCallback;
import com.serenegiant.usb.Size;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.USBMonitor.OnDeviceConnectListener;
import com.serenegiant.usb.USBMonitor.UsbControlBlock;
import com.serenegiant.usb.UVCCamera;
import com.serenegiant.widget.UVCCameraTextureView;
import com.shenyaocn.android.Encoder.AVWriter;
import com.squareup.picasso.Picasso;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.shenyaocn.android.dualcamera.Helper.findAudioRecord;

public final class MainActivity extends AppCompatActivity implements CameraDialog.CameraDialogParent {
	private static final boolean DEBUG = true;	// 用于显示调试信息
	private static final String TAG = "MainActivity";

	private AVWriter avWriterL = new AVWriter();	// 用于左边摄像头录像
	private AVWriter avWriterR = new AVWriter();	// 用于右边摄像头录像

	private AudioThread audioThread;				// 录音线程
	private AudioRecord audioRecord;
	private int bufferSize;

    private USBMonitor mUSBMonitor;					// 用于监视USB设备接入
	private UVCCamera mUVCCameraL;					// 表示左边摄像头设备
	private UVCCamera mUVCCameraR;					// 表示右边摄像头设备

	private OutputStream snapshotOutStreamL;		// 用于左边摄像头拍照
	private String snapshotFileNameL;

	private OutputStream snapshotOutStreamR;		// 用于右边摄像头拍照
	private String snapshotFileNameR;

	private static final float[] BANDWIDTH_FACTORS = { 0.5f, 0.5f };

	private int currentWidth = UVCCamera.DEFAULT_PREVIEW_WIDTH;
	private int currentHeight = UVCCamera.DEFAULT_PREVIEW_HEIGHT;

	private UVCCameraTextureView mUVCCameraViewR;	// 用于右边摄像头预览
	private Surface mRightPreviewSurface;

	private UVCCameraTextureView mUVCCameraViewL;	// 用于左边摄像头预览
	private Surface mLeftPreviewSurface;

	private ImageButton mRecordButton;
	private ImageButton mCaptureButton;
	private String tag;
	private boolean sure;
	private TextView time;
	private String times="";
	private String GPS="0-0";
	private String speed="";
	private String studentID="";
	private String teacherID="";
	private String schoolID="";
	private String carID="";
	private String gps="";
	private String type="";

	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d(TAG, "*********onCreate");
		Intent intent = getIntent();
		studentID=intent.getStringExtra("studentid");
		schoolID = intent.getStringExtra("schoolID");
		type = intent.getStringExtra("cmd");
		teacherID = intent.getStringExtra("teacherID");
		speed = intent.getStringExtra("speed");
		carID = intent.getStringExtra("carID");
		gps = intent.getStringExtra("GPS");
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true){
					while (count>0){
						count--;
						try {
							Thread.sleep(1000);
							handler.sendEmptyMessage(500);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}).start();
		Window window = getWindow();
		requestWindowFeature(Window.FEATURE_NO_TITLE);//remove title bar  即隐藏标题栏
		getSupportActionBar().hide();// 隐藏ActionBar
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//remove notification bar  即全屏
		window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // 避免屏幕关闭
		WindowManager wm= (WindowManager) getSystemService(WINDOW_SERVICE);
		int width = wm.getDefaultDisplay().getWidth();
		int height = wm.getDefaultDisplay().getHeight();
		setContentView(R.layout.activity_main);
		com.rscja.deviceapi.OTG.getInstance().on(); //打开OTG
		mUVCCameraViewL = (UVCCameraTextureView)findViewById(R.id.camera_view_L);
		mUVCCameraViewL.setAspectRatio(width/ (float)height);

		mUVCCameraViewR = (UVCCameraTextureView)findViewById(R.id.camera_view_R);
		mUVCCameraViewR.setAspectRatio(UVCCamera.DEFAULT_PREVIEW_WIDTH / (float)UVCCamera.DEFAULT_PREVIEW_HEIGHT);

		mRecordButton = (ImageButton)findViewById(R.id.record_button);
		mRecordButton.setOnClickListener(mOnClickListener);

		mCaptureButton = (ImageButton)findViewById(R.id.capture_button);
		mCaptureButton.setOnClickListener(mOnClickListener);

		mUVCCameraViewL.setOnClickListener(mOnClickListener);
		mUVCCameraViewR.setOnClickListener(mOnClickListener);
		new Thread(new Runnable() {
			int count=7;
			@Override
			public void run() {
				while (count>1){
					count--;
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (4>count) {
						Intent it = new Intent("com.scstjy.picspeak");
						it.putExtra("count",count);
						sendBroadcast(it);
					}
					if (count==1) {
						captureSnapshot();
					}
				}
			}
		}).start();
		refreshControls();

		mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);
		final List<DeviceFilter> filters = DeviceFilter.getDeviceFilters(this, R.xml.device_filter);
		mUSBMonitor.setDeviceFilter(filters);

	}

	@Override
	protected void onStart() {
		super.onStart();
		mUSBMonitor.register();//start
		refreshControls();
		
	}

	@Override
	protected void onStop() {
        mUSBMonitor.unregister();
        super.onStop();
	}

	@Override
	protected void onPause() {

		// Activity暂停时要释放左右摄像头并停止录像
		super.onPause();
	}

	// 刷新UI控件状态
	private void refreshControls() {
		try {
			boolean enabled = (mUVCCameraL != null || mUVCCameraR != null);

			findViewById(R.id.record_button).setEnabled(enabled);
			findViewById(R.id.capture_button).setEnabled(enabled);

			((ImageButton)findViewById(R.id.record_button)).setImageResource((avWriterL.isOpened() || avWriterR.isOpened()) ? R.drawable.ic_action_record_stop : R.drawable.ic_action_record);

			findViewById(R.id.textViewUVCPromptL).setVisibility(mUVCCameraL != null ? View.GONE : View.VISIBLE);
			findViewById(R.id.textViewUVCPromptR).setVisibility(mUVCCameraR != null ? View.GONE : View.VISIBLE);

			invalidateOptionsMenu();
		} catch (Exception e){}
	}

	private synchronized void releaseCameraL() {
		synchronized (this) {
			stopRecord(avWriterL);
			if (mUVCCameraL != null) {
				try {
					mUVCCameraL.setStatusCallback(null);
					mUVCCameraL.setButtonCallback(null);
                    //mUVCCameraL.close();
					mUVCCameraL.destroy();
				} catch (final Exception e) {
                    Log.e(TAG, e.getMessage());
				}
				mUVCCameraL = null;
			}

			if (mLeftPreviewSurface != null) {
				mLeftPreviewSurface.release();
				mLeftPreviewSurface = null;
			}

			findViewById(R.id.textViewUVCPromptL).setVisibility(View.VISIBLE);
		}
	}

	private synchronized void releaseCameraR() {
		synchronized (this) {
			stopRecord(avWriterR);
			if (mUVCCameraR != null) {
				try {
					mUVCCameraR.setStatusCallback(null);
					mUVCCameraR.setButtonCallback(null);
                    //mUVCCameraR.close();
					mUVCCameraR.destroy();
				} catch (final Exception e) {
                    Log.e(TAG, e.getMessage());
				}
				mUVCCameraR = null;
			}

			if (mRightPreviewSurface != null) {
				mRightPreviewSurface.release();
				mRightPreviewSurface = null;
			}
			findViewById(R.id.textViewUVCPromptR).setVisibility(View.VISIBLE);
		}
	}
	private boolean isFinish=false;
	@Override
	protected void onDestroy() {




        //mUSBMonitor.unregister();

		releaseCameraL();
		releaseCameraR();
		stopAudio();

		if (mUSBMonitor != null) {
			mUSBMonitor.destroy();
			mUSBMonitor = null;
		}
		com.rscja.deviceapi.OTG.getInstance().off(); //关闭OTG
		super.onDestroy();
	}

	private void processAudio(byte[] buffer, int length) {
		if(avWriterL.isAudioEncoderOpened()) {
			avWriterL.putAudio(buffer, length);
		}

		if(avWriterR.isAudioEncoderOpened()) {
			avWriterR.putAudio(buffer, length);
		}
		// 将麦克风捕获的PCM音频数据分别发送给编码器
	}

	private class AudioThread extends Thread {
		private boolean bRun = true;
		public void run() {
			setName("AudioThread");
			byte[] buffer = new byte[bufferSize];
			try {
				while(bRun) {

					int bufferReadResult = audioRecord.read(buffer, 0, buffer.length);
					if(bufferReadResult <= 0) {
						Thread.sleep(100);
						continue;
					}

					processAudio(buffer, bufferReadResult);
				}
			} catch (Exception e) {
				Log.e("AudioThread", e.getMessage());
			}
		}

		public void cancel() {
			bRun = false;
		}
	}

	// 开始麦克风捕获
	private synchronized boolean startAudio() {

		if(audioRecord != null || audioThread != null) // 如果已经打开了就直接返回
			return true;

		int[] bufferSizes = new int[1];

		audioRecord = findAudioRecord(true, bufferSizes); // 参考具体函数实现
		bufferSize = bufferSizes[0];
		if (audioRecord == null) {
			return false;
		}

		audioRecord.startRecording();

		audioThread = new AudioThread();
		audioThread.start();

		return true;
	}

	private synchronized void stopAudio() {

		if (audioThread != null)
			audioThread.cancel();

		if (audioRecord != null) {
			try {
				audioRecord.stop();
				audioRecord.release();
				audioRecord = null;
			} catch (Exception e) {
			}
		}
		audioThread = null;
	}

	// 实现快照抓取
	private synchronized void captureSnapshot() {
		Log.e("MainActivity","开始准备拍照");
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(1000);
					Log.e("MainActivity","开始拍照");
					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd.HH.mm.ss.SSSS");
					String tm = format.format(new Date(System.currentTimeMillis()));

					snapshotFileNameL = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DualCamera/";

					snapshotFileNameL += studentID+""+tm;
					snapshotFileNameL += "_L.jpg";
					File recordFile = new File(snapshotFileNameL);	// 左边摄像头快照的文件名
					File f = recordFile.getParentFile();
					if (!f.exists()) {
						f.mkdirs();
					}
					if(recordFile.exists()) {
						recordFile.delete();
					}
					try {
						recordFile.createNewFile();
						snapshotOutStreamL = new FileOutputStream(recordFile);
					} catch (Exception e){}

					snapshotFileNameR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ShenTongPic";
					snapshotFileNameR += studentID;
					snapshotFileNameR += tm;
					snapshotFileNameR += ".jpg";
					recordFile = new File(snapshotFileNameR);		// 右边摄像头快照的文件名
					if(recordFile.exists()) {
						recordFile.delete();
					}
					try {
						recordFile.createNewFile();
						snapshotOutStreamR = new FileOutputStream(recordFile);
					} catch (Exception e){}


					Thread.sleep(2000);
					Bitmap bitmap = BitmapFactory.decodeFile(snapshotFileNameL).copy(Bitmap.Config.ARGB_8888,true);
					addWaterMask(bitmap);
					try {
						bitmap.compress(Bitmap.CompressFormat.JPEG,50,new FileOutputStream(snapshotFileNameL));
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					}
					handler.sendEmptyMessage(800);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	private void addWaterMask(Bitmap bm1) {
		int height = bm1.getHeight();
		int width = bm1.getWidth();
		Paint p = new Paint();
		p.setTextSize(16);
		p.setColor(Color.RED);
		Canvas canvas = new Canvas(bm1);
		//计算文字位置 居中显示
		String text="神通测试图片";
		long l = System.currentTimeMillis();
		times = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(l));
		Paint.FontMetrics fontMetrics = p.getFontMetrics();
		float top = fontMetrics.bottom-fontMetrics.top;
		canvas.drawText("驾校编号:"+schoolID,0,top,p);
		canvas.drawText("教练员编号:"+teacherID,0,2*top,p);
		canvas.drawText("学员编号:"+studentID,0,3*top,p);
		canvas.drawText("车牌号"+carID,0,height-top,p);
		canvas.drawText("车速:"+speed+"km/h",0,height-2*top,p);
		float v = p.measureText(times);
		canvas.drawText("当前时间:"+times,width-2*v,height,p);
		float v1 = p.measureText(GPS);
		canvas.drawText("GPS:"+GPS,width-3*v1,height-top,p);
		canvas.save(Canvas.ALL_SAVE_FLAG);
	}
	private int count=0;
	private AlertDialog dialog;
	private void show(final String path) {
		sure=true;
		count=14;
		AlertDialog.Builder bd=new AlertDialog.Builder(this,R.style.Dialog_Fullscreen);
		View v = getLayoutInflater().inflate(R.layout.activity_show, null, false);
		Button right= (Button) v.findViewById(R.id.reload);
		LinearLayout cancle= (LinearLayout) v.findViewById(R.id.mksuer);
		time= (TextView) v.findViewById(R.id.mtimes);
		ImageView bg= (ImageView) v.findViewById(R.id.mshow_view);
		try {
			FileInputStream fis = new FileInputStream(new File(path));
			Bitmap bitmap = BitmapFactory.decodeStream(fis);
			int byteCount = bitmap.getByteCount();
			Log.e("MainActivity",byteCount+"字节数");
			bg.setImageBitmap(bitmap);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		bd.setView(v);
		dialog = bd.create();
		dialog.show();
		Log.e("MainActivity","显示Dialog成功");
		dialog.setOnShowListener(new DialogInterface.OnShowListener() {
			@Override
			public void onShow(DialogInterface dialog) {

				time.setText("("+count+"s)");
			}
		});
		cancle.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();

			}
		});
		right.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				sure=false;
				dialog.dismiss();
			}
		});
		dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
			@Override
			public void onDismiss(DialogInterface dialog) {
				if (sure) {
					Intent intent = getIntent();
					Intent it = new Intent("com.scstjy.piccomlite");
					it.putExtra("state","success");
					it.putExtra("type",type);
					it.putExtra("path",path);
					sendBroadcast(it);
					isFinish=true;
					new Thread(new Runnable() {
						@Override
						public void run() {
							File f = new File(path);
							File pa = f.getParentFile();
							File[] files = pa.listFiles();
							for (File file : files) {
								if (file.getName().endsWith(".jpg")) {
									if (System.currentTimeMillis()-file.lastModified()>86400000*3) {
										file.delete();
									}
								}
							}
						}
					}).start();
					finish();
				}else {
					captureSnapshot();
				}
			}
		});

	}
	Handler handler=new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (msg.what==500) {
				if (count>0){
					if (time!=null) {
						time.setText("("+count+"s)");
					}
				}else {
					if(dialog!=null){
						if (dialog.isShowing()) {
							dialog.dismiss();
						}
					}
				}
			}else if (msg.what==800){
				show(snapshotFileNameL);
			}
		}
	};
	private void openAVWriter(String fileName, AVWriter avWriter, UVCCamera uvcCamera) {
		Size size = uvcCamera.getPreviewSize();
		if(audioRecord != null) {
			avWriter.open(fileName, size.width, size.height, audioRecord.getSampleRate(), audioRecord.getChannelCount());
		} else {
			avWriter.open(fileName, size.width, size.height, 0, 0);
		}
	}
	
	private void startRecord(AVWriter avWriter, UVCCamera uvcCamera) {
		if(avWriter.isOpened()) {
			return;
		}

		if(uvcCamera == null) {
			return;
		}

		String extra = "L";

		if(uvcCamera == mUVCCameraR) // 通过判断是左边还是右边的摄像头来调整文件名
			extra = "R";

		String fileName = Helper.getVideoFileName(extra); // 可以参考函数实现

		openAVWriter(fileName, avWriter, uvcCamera);

		if(avWriter.isOpened()) {
			startRecTimer(); // 如果编码器打开成功，则开始录像计时
		}
	}

	// 录像计时器的实现部分
	public static String sec2time(int second){
		int h = 0;
		int d = 0;
		int s = 0;
		int temp = second%3600;
		if(second>3600){
			h= second/3600;
			if(temp!=0){
				if(temp>60){
					d = temp/60;
					if(temp%60!=0){
						s = temp%60;
					}
				}else{
					s = temp;
				}
			}
		}else{
			d = second/60;
			if(second%60!=0){
				s = second%60;
			}
		}

		return String.format("%02d:%02d:%02d", h, d, s);
	}

	private int timer_count = 0;
	private Timer timer;

	public String getRecordTimeCount() {
		return sec2time(timer_count) + (timer_count % 2 == 0 ? " REC" : "");
	}

	private void startRecTimer() {
		stopRecTimer();
		timer_count = 0;

		timer = new Timer(true);
		timer.schedule(new TimerTask(){
			public void run() {
				timer_count++;
			}
		},1000, 1000);
	}

	private void stopRecTimer() {
		if(timer != null) {
			timer.cancel();
			timer.purge();
			timer = null;
		}
		timer_count = 0;
	}

	private void stopRecord(AVWriter avWriter) {
		stopRecTimer();

		if(!avWriter.isOpened()) {
			return;
		}

		final String fileName = avWriter.getRecordFileName();
		avWriter.close(new AVWriter.ClosedCallback() {
			@Override
			public void closedCallback() {	// 录像文件编码完成时的异步回调
				Helper.fileSavedProcess(MainActivity.this, fileName); // 通知媒体扫描器扫描媒体文件以便在图库等app可见，可以参见函数实现
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(MainActivity.this, "\"" + fileName + "\"", Toast.LENGTH_LONG).show();
					}
				});
			}
		});
	}

	private final OnClickListener mOnClickListener = new OnClickListener() {
		@Override
		public void onClick(final View view) {
			switch (view.getId()) {
				case R.id.capture_button:
					captureSnapshot();
					break;
				case R.id.record_button:
					if (mUVCCameraL != null) {
						if (avWriterL.isOpened()) {
							stopRecord(avWriterL);
						} else {
							startRecord(avWriterL, mUVCCameraL);
						}
					}

					if (mUVCCameraR != null) {
						if (avWriterR.isOpened()) {
							stopRecord(avWriterR);
						} else {
							startRecord(avWriterR, mUVCCameraR);
						}
					}
					// 实现录像功能，分别开始左右摄像头的录像

					refreshControls();

					break;
			}
		}
	};

	private final OnDeviceConnectListener mOnDeviceConnectListener = new OnDeviceConnectListener() {
		@Override
		public void onAttach(final UsbDevice device) {
			if (DEBUG) Log.i(TAG, "onAttach:" + device);
			final List<UsbDevice> list = mUSBMonitor.getDeviceList();
			mUSBMonitor.requestPermission(list.get(0));

			if(list.size() > 1)
				new Handler().postDelayed(new Runnable() {public void run() {mUSBMonitor.requestPermission(list.get(1));}}, 200);
		}

		@Override
		public void onConnect(final UsbDevice device, final UsbControlBlock ctrlBlock, final boolean createNew) {

			if (DEBUG) Log.i(TAG, "onConnect:"+ctrlBlock.getVenderId());
			synchronized (this) {
				if (mUVCCameraL != null && mUVCCameraR != null) { // 如果左右摄像头都打开了就不能再接入设备了
					return;
				}
				if (ctrlBlock.getVenderId() == 2){
					if (mUVCCameraL != null && mUVCCameraL.getDevice().equals(device)){
						return;
					}
				} else if (ctrlBlock.getVenderId() == 3) {
					if ((mUVCCameraR != null && mUVCCameraR.getDevice().equals(device))) {
						return;
					}
				}else {
					return;
				}
				final UVCCamera camera = new UVCCamera();
				final int open_camera_nums = (mUVCCameraL != null ? 1 : 0) + (mUVCCameraR != null ? 1 : 0);
				camera.open(ctrlBlock);

				try {
					camera.setPreviewSize(currentWidth, currentHeight, UVCCamera.FRAME_FORMAT_MJPEG, 0.5f); // 0.5f是一个重要参数，表示带宽可以平均分配给两个摄像头，如果是一个摄像头则是1.0f，可以参考驱动实现
				} catch (final IllegalArgumentException e1) {
					if (DEBUG) Log.i(TAG, "MJPEG Failed");
					try {
						camera.setPreviewSize(currentWidth, currentHeight, UVCCamera.DEFAULT_PREVIEW_MODE, 0.5f);
					} catch (final IllegalArgumentException e2) {
						try {
							currentWidth = UVCCamera.DEFAULT_PREVIEW_WIDTH;
							currentHeight = UVCCamera.DEFAULT_PREVIEW_HEIGHT;
							camera.setPreviewSize(currentWidth, currentHeight, UVCCamera.DEFAULT_PREVIEW_MODE, 0.5f);
						} catch (final IllegalArgumentException e3) {
							camera.destroy();

							runOnUiThread(new Runnable() {
								@Override
								public void run() {
									//Toast.makeText(ShowCameraViewActivity.this, "UVC设备错误", Toast.LENGTH_LONG).show();
								}
							});

							return;
						}
					}
				}

				// 将摄像头进行分配
				if(ctrlBlock.getVenderId() == 2 && mUVCCameraL == null) {
					mUVCCameraL = camera;
					if (mLeftPreviewSurface != null) {
						mLeftPreviewSurface.release();
						mLeftPreviewSurface = null;
					}

					final SurfaceTexture st = mUVCCameraViewL.getSurfaceTexture();
					if (st != null)
						mLeftPreviewSurface = new Surface(st);
					mUVCCameraL.setPreviewDisplay(mLeftPreviewSurface);

					mUVCCameraL.setFrameCallback(mUVCFrameCallbackL, UVCCamera.PIXEL_FORMAT_YUV420SP);
					mUVCCameraL.startPreview();
				} else if(ctrlBlock.getVenderId() == 3 && mUVCCameraR == null) {
					mUVCCameraR = camera;
					if (mRightPreviewSurface != null) {
						mRightPreviewSurface.release();
						mRightPreviewSurface = null;
					}

					final SurfaceTexture st = mUVCCameraViewR.getSurfaceTexture();
					if (st != null)
						mRightPreviewSurface = new Surface(st);
					mUVCCameraR.setPreviewDisplay(mRightPreviewSurface);

					mUVCCameraR.setFrameCallback(mUVCFrameCallbackR, UVCCamera.PIXEL_FORMAT_YUV420SP);
					mUVCCameraR.startPreview();

				}
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						refreshControls();

                  //      if (mUVCCameraL != null || mUVCCameraR != null)
                  //      startAudio();
					}
				});
			}
		}

		@Override
		public void onDisconnect(final UsbDevice device, final UsbControlBlock ctrlBlock) {
			if (DEBUG) Log.v(TAG, "onDisconnect:" + device);
			if ((mUVCCameraL != null) && mUVCCameraL.getDevice().equals(device)) {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						releaseCameraL();
					}
				});

			} else if ((mUVCCameraR != null) && mUVCCameraR.getDevice().equals(device)) {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						releaseCameraR();
					}
				});
			}

			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					refreshControls();
					if(mUVCCameraL == null && mUVCCameraR == null)
						stopAudio();
				}
			});
		}

		@Override
		public void onDettach(final UsbDevice device) {
			if (DEBUG) Log.v(TAG, "onDettach:" + device);
			Toast.makeText(MainActivity.this, "USB设备断开", Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onCancel(final UsbDevice device) {
			if (DEBUG) Log.v(TAG, "onCancel:");
		}
	};

	// 左边摄像头的NV21视频帧回调
	private final IFrameCallback mUVCFrameCallbackL = new IFrameCallback() {
		@Override
		public void onFrame(final ByteBuffer frame) {

			if(mUVCCameraL == null)
				return;

			final Size size = mUVCCameraL.getPreviewSize();
			byte[] buffer = null;

			if (avWriterL.isVideoEncoderOpened()) { // 将视频帧发送到编码器
				if (buffer == null) {
					buffer = new byte[frame.remaining()];
					frame.get(buffer);
				}
				avWriterL.putFrame(buffer, size.width, size.height);
			}

			if(snapshotOutStreamL != null) { // 将视频帧压缩成jpeg图片，实现快照捕获
				if (buffer == null) {
					buffer = new byte[frame.remaining()];
					frame.get(buffer);
				}
				try {
					new YuvImage(buffer, ImageFormat.NV21, size.width, size.height, null).compressToJpeg(new Rect(0, 0, size.width, size.height), 90, snapshotOutStreamL);
					snapshotOutStreamL.flush();
					snapshotOutStreamL.close();
					Helper.fileSavedProcess(MainActivity.this, snapshotFileNameL);
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
                            //Toast.makeText(ShowCameraViewActivity.this, "\"" + snapshotFileNameL + "\"", Toast.LENGTH_SHORT).show();
						}
					});
				} catch (Exception ex) {
				} finally {
					snapshotOutStreamL = null;
				}
			}
		}
	};

	// 参考上面的注释
	private final IFrameCallback mUVCFrameCallbackR = new IFrameCallback() {
		@Override
		public void onFrame(final ByteBuffer frame) {

			if(mUVCCameraR == null)
				return;

			final Size size = mUVCCameraR.getPreviewSize();
			byte[] buffer = null;

			if (avWriterR.isVideoEncoderOpened()) {
				if (buffer == null) {
					buffer = new byte[frame.remaining()];
					frame.get(buffer);
				}
				avWriterR.putFrame(buffer, size.width, size.height);
			}

			if(snapshotOutStreamR != null) {
				if (buffer == null) {
					buffer = new byte[frame.remaining()];
					frame.get(buffer);
				}
				try {
					new YuvImage(buffer, ImageFormat.NV21, size.width, size.height, null).compressToJpeg(new Rect(0, 0, size.width, size.height), 90, snapshotOutStreamR);
					snapshotOutStreamR.flush();
					snapshotOutStreamR.close();
					Helper.fileSavedProcess(MainActivity.this, snapshotFileNameR);
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
                            //Toast.makeText(ShowCameraViewActivity.this, "\"" + snapshotFileNameR + "\"", Toast.LENGTH_SHORT).show();
						}
					});
				} catch (Exception ex) {
				} finally {
					snapshotOutStreamR = null;
				}
			}
		}
	};

	/**
	 * to access from CameraDialog
	 * @return
	 */
	@Override
	public USBMonitor getUSBMonitor() {
		return mUSBMonitor;
	}

	@Override
	public void onDialogResult(boolean canceled) {

	}
}
